﻿////////////////////////////////////////////////////////////////////
//
//	Map_FVG C# Class Library.
//
//	Scarpata
//	traciamento scarpate, limiti di bosco,arenili ed aree di roccia
//
//
//	autore: Gustavo Mainardi 
//	versione: 1.0
//	data: 01/12/2015
//
//
//	Cronologia delle versioni:
//
//	Versione 1.0 01/12/2015
//		versione originale
//
//////////////////////////////////////////////////////////////////////////
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Globalization;
using PdfFileWriter;


namespace Map_Fvg
{
    public partial class Scarpata
    {
        public Scarpata()
        {

        }


        public void scarpata(Pen iPen, Point[] polygon, float width, float dash0, float dash1, float interp, Graphics dc0, int ist, int itype)
        {
            int nPoint = polygon.Length;
            if (nPoint < 3) return;
            PointF[] polyg = new PointF[nPoint];
            for (int i = 0; i < nPoint; ++i)
            {
                polyg[i].X = (float)polygon[i].X;
                polyg[i].Y = (float)polygon[i].Y;
            }
            scarpata(iPen, polyg, width, dash0, dash1, interp, dc0, ist, itype);
        }

        public void scarpata(Pen iPen, PointF[] polygon, float width, float dash0, float dash1, float interp, Graphics dc0, int ist, int type)
        {
            int nPoint = polygon.Length;
            if (nPoint < 3) return;
            float ilen = polyLength(polygon, nPoint);
            if (ilen < 3 * interp) return;
            int maxPt = 2 * nPoint;  // 3 * (int)(ilen / interp);
            int maxPt1 = 3 * (int)(ilen / interp);
            if (maxPt1 > maxPt) maxPt = maxPt1;

            PointF[] poly1 = new PointF[1];
            float interp1 = 0.2F * interp;
            normalize(polygon, ref poly1, interp1, ist);
            int nPoint1 = poly1.Length;

            if (nPoint1 < 3) return;

            PointF[] poly22 = new PointF[maxPt];
            int nPoints = newPoint(poly1, ref poly22, interp, maxPt, ist);
            PointF[] poly2 = new PointF[nPoints];
            for (int i = 0; i < nPoints; ++i) poly2[i] = poly22[i];

            poly1 = new PointF[nPoints];

            float dash00 = dash0;
            float dash11 = dash1;
            if (ViewQ.scalaXY < 2)
            {
                dash00 = dash0 / 2;
                dash11 = dash1 / 2;
            }
            if (type == 11 || type == 13) puntoAdiacente(poly2, ref poly1, nPoints, dash00, dash11, ist);
            if (type == 12) puntoAdiacente1(ref poly2, ref poly1, nPoints, dash00, dash11, ist);
            iPen.Width = width;
            for (int j = 0; j < nPoints; ++j)
            {
                //             dc0.DrawLine(iPen, poly2[j], poly1[j]);
            }
            if (type == 13)
            {
                dc0.DrawCurve(iPen, poly2);
            }
        }

        float polyLength(Point[] polygon, int count)
        {
            float ilen = 0;

            for (int i = 0; i < count - 1; ++i)
            {
                double dx = (double)(polygon[i + 1].X - polygon[i].X);
                double dy = (double)(polygon[i + 1].Y - polygon[i].Y);
                double ds = dx * dx + dy * dy;
                float incr = (float)(Math.Sqrt(ds));
                ilen += incr;
            }
            return ilen;
        }

        void normalize(Point[] polygon, ref PointF[] poly, float interp, int ist)
        {
            int nPoint = polygon.Length;
            PointF[] poly1 = new PointF[nPoint];
            poly1[0] = polygon[0];
            int ipt = 1;
            double dinterp = (double)interp;
            for (int i = 1; i < nPoint; ++i)
            {
                double dx = polygon[i].X - poly1[ipt - 1].X;
                double dy = polygon[i].Y - poly1[ipt - 1].Y;
                double ds = Math.Sqrt(dx * dx + dy * dy);
                if (ds >= dinterp)
                {
                    poly1[ipt] = polygon[i];
                    ++ipt;
                }

            }
            poly = new PointF[ipt];
            for (int i = 0; i < ipt; ++i) poly[i] = poly1[i];

        }


        float polyLength(PointF[] polygon, int count)
        {
            float ilen = 0;

            for (int i = 0; i < count - 1; ++i)
            {
                double dx = (double)(polygon[i + 1].X - polygon[i].X);
                double dy = (double)(polygon[i + 1].Y - polygon[i].Y);
                double ds = dx * dx + dy * dy;
                float incr = (float)(Math.Sqrt(ds));
                ilen += incr;
            }
            return ilen;
        }

        void normalize(PointF[] polygon, ref PointF[] poly, float resol, int ist)
        {
            int nPoint = polygon.Length;
            PointF[] poly1 = new PointF[nPoint];
            poly1[0] = polygon[0];
            int ipt = 1;
            double dresol = (double)resol;
            for (int i = 1; i < nPoint; ++i)
            {
                double dx = polygon[i].X - poly1[ipt - 1].X;
                double dy = polygon[i].Y - poly1[ipt - 1].Y;
                double ds = Math.Sqrt(dx * dx + dy * dy);
                if (ds >= dresol)
                {
                    poly1[ipt] = polygon[i];
                    ++ipt;
                }


            }
            poly = new PointF[ipt];
            for (int i = 0; i < ipt; ++i) poly[i] = poly1[i];

        }

        void puntoAdiacente(PointF[] poly1, ref PointF[] poly2, int count, float dash0, float dash1, int ist)
        {

            if (dash0 == 0) return;

            double ds = dash0;
            double ds1 = dash1;
            bool bShort = true;
            for (int i = 1; i < count; ++i)
            {
                if (bShort) bShort = false;
                else bShort = true;

                double dx1 = poly1[i].X - poly1[i - 1].X;
                double dy1 = poly1[i].Y - poly1[i - 1].Y;
                double dlen = Math.Sqrt(dx1 * dx1 + dy1 * dy1);
                double ddss;
                float dss;
                if (dx1 == 0)
                {
                    if (bShort) dss = dash1;
                    else dss = dash0;
                    if (dy1 < 0) dss = -dss;
                    poly2[i].X = poly1[i].X - dss;
                    poly2[i].Y = poly1[i].Y;
                    continue;
                }
                if (dy1 == 0)
                {
                    if (bShort) dss = dash1;
                    else dss = dash0;
                    if (dx1 > 0) dss = -dss;
                    poly2[i].X = poly1[i].X;
                    poly2[i].Y = poly1[i].Y - dss;
                    continue;
                }

                if (bShort) ddss = dash1;
                else ddss = dash0;
                double tan3 = -dx1 / dy1;
                //   >       double tan4 = (tan3 - tan2) / (1 + tan3 * tan2);
                double den = Math.Sqrt(1 + tan3 * tan3);
                double cos3 = 1 / den;
                double sin3 = Math.Abs(tan3 / den);
                double dx = ddss * cos3;
                if (dx1 < 0 && dy1 < 0) dx = -dx;
                if (dx1 > 0 && dy1 < 0) dx = -dx;

                double dy = ddss * sin3;
                if (dx1 > 0 && dy1 > 0) dy = -dy;
                if (dx1 > 0 && dy1 < 0) dy = -dy;

                poly2[i].X = poly1[i].X - (float)dx;
                poly2[i].Y = poly1[i].Y - (float)dy;
            }

            PointF dPt = new PointF(0, 0);
            dPt.X = poly1[1].X - poly2[1].X;
            dPt.Y = poly1[1].Y - poly2[1].Y;
            poly2[0].X = poly1[0].X + dPt.X;
            poly2[0].Y = poly1[0].Y + dPt.Y;
            dPt.X = poly1[count - 2].X - poly2[count - 2].X;
            dPt.Y = poly1[count - 2].Y - poly2[count - 2].Y;
            poly2[count - 1].X = poly1[count - 1].X + dPt.X;
            poly2[count - 1].Y = poly1[count - 1].Y + dPt.Y;

        }

        void puntoAdiacente1(ref PointF[] poly1, ref PointF[] poly2, int count, float dash0, float dash1, int ist)
        {
            //  scarpata (piede)

            if (dash0 == 0) return;

            double ds = dash0;
            double ds1 = dash1;
            for (int i = 1; i < count; ++i)
            {
                double dx1 = poly1[i].X - poly1[i - 1].X;
                double dy1 = poly1[i].Y - poly1[i - 1].Y;
                double dlen = Math.Sqrt(dx1 * dx1 + dy1 * dy1);
                float dss = dash0;
                if (dx1 == 0)
                {
                    if (dy1 < 0) dss = -dss;
                    poly2[i].X = poly1[i].X - dss;
                    poly2[i].Y = poly1[i].Y;
                    continue;
                }
                if (dy1 == 0)
                {
                    if (dx1 > 0) dss = -dss;
                    poly2[i].X = poly1[i].X;
                    poly2[i].Y = poly1[i].Y - dss;
                    continue;
                }

                double tan3 = -dx1 / dy1;
                //   >       double tan4 = (tan3 - tan2) / (1 + tan3 * tan2);
                double den = Math.Sqrt(1 + tan3 * tan3);
                double cos3 = 1 / den;
                double sin3 = Math.Abs(tan3 / den);
                double dx = ds * cos3;
                if (dx1 < 0 && dy1 < 0) dx = -dx;
                if (dx1 > 0 && dy1 < 0) dx = -dx;

                double dy = ds * sin3;
                if (dx1 > 0 && dy1 > 0) dy = -dy;
                if (dx1 > 0 && dy1 < 0) dy = -dy;

                poly2[i].X = poly1[i].X - (float)dx;
                poly2[i].Y = poly1[i].Y - (float)dy;
            }

            PointF dPt = new PointF(0, 0);
            dPt.X = poly1[1].X - poly2[1].X;
            dPt.Y = poly1[1].Y - poly2[1].Y;
            poly2[0].X = poly1[0].X + dPt.X;
            poly2[0].Y = poly1[0].Y + dPt.Y;
            dPt.X = poly1[count - 2].X - poly2[count - 2].X;
            dPt.Y = poly1[count - 2].Y - poly2[count - 2].Y;
            poly2[count - 1].X = poly1[count - 1].X + dPt.X;
            poly2[count - 1].Y = poly1[count - 1].Y + dPt.Y;

            bool bShort = true;
            for (int i = 1; i < count; ++i)
            {
                if (bShort) bShort = false;
                else bShort = true;
                if (bShort)
                {
                    double dx1 = poly1[i].X - poly1[i - 1].X;
                    double dy1 = poly1[i].Y - poly1[i - 1].Y;
                    double dlen = Math.Sqrt(dx1 * dx1 + dy1 * dy1);
                    float dss = dash0 - dash1;
                    if (dx1 == 0)
                    {
                        if (dy1 < 0) dss = -dss;
                        poly1[i].X = poly1[i].X - dss;
                        poly1[i].Y = poly1[i].Y;
                        continue;
                    }
                    if (dy1 == 0)
                    {
                        if (dx1 > 0) dss = -dss;
                        poly1[i].X = poly1[i].X;
                        poly1[i].Y = poly1[i].Y - dss;
                        continue;
                    }
                    double dds = dash0 - dash1;
                    double tan3 = -dx1 / dy1;
                    //   >       double tan4 = (tan3 - tan2) / (1 + tan3 * tan2);
                    double den = Math.Sqrt(1 + tan3 * tan3);
                    double cos3 = 1 / den;
                    double sin3 = Math.Abs(tan3 / den);
                    double dx = dds * cos3;
                    if (dx1 < 0 && dy1 < 0) dx = -dx;
                    if (dx1 > 0 && dy1 < 0) dx = -dx;

                    double dy = dds * sin3;
                    if (dx1 > 0 && dy1 > 0) dy = -dy;
                    if (dx1 > 0 && dy1 < 0) dy = -dy;

                    poly1[i].X = poly1[i].X - (float)dx;
                    poly1[i].Y = poly1[i].Y - (float)dy;

                }
            }
        }


        int newPoint(PointF[] poly1, ref PointF[] poly2, float interp, int maxIpt, int ist)
        {

            int ilen = poly1.Length;

            poly2[0] = poly1[0];
            int ipt = 1;
            double dint = (double)interp;
            double dint1 = dint;
            double seg1 = 0;

            for (int i = 1; i < ilen; ++i)
            {
                double dx = poly1[i].X - poly1[i - 1].X;
                double dy = poly1[i].Y - poly1[i - 1].Y;
                double len = Math.Sqrt(dx * dx + dy * dy);
                double incrX = 0;
                double incrY = 0;
            L10:
                ;
                double diff = len - seg1 - dint1;
                if (diff >= 0)
                {
                    double cos1 = dx / len;
                    double sin1 = dy / len;

                    incrX += dint1 * cos1;
                    incrY += dint1 * sin1;

                    poly2[ipt].X = poly1[i - 1].X + (float)incrX;
                    poly2[ipt].Y = poly1[i - 1].Y + (float)incrY;
                    ++ipt;
                    if (ipt == maxIpt) break;
                    seg1 += dint1;
                    dint1 = dint;
                    goto L10;
                }

                if (diff < 0)
                {
                    dint1 = dint1 - len + seg1;
                    seg1 = 0;
                }
            }

            return (ipt);

        }


        public void arenile(Graphics dc0, Pen iPen, Point[] polygon, float dash0, float dash1, float dist_linee, float offset, int ist)
        {

            PointF[] poly1 = new PointF[1];
            float interp = 2;
            normalize(polygon, ref poly1, interp, ist);

            int nPoints = poly1.Length;
            PointF[] poly = new PointF[nPoints + 1];

            for (int i = 0; i < nPoints; ++i) poly[i] = poly1[i];

            float yMin = poly[0].Y;
            float yMax = poly[0].Y;
            float xMin = poly[0].X;
            float xMax = poly[0].X;
            int minY = 0;
            for (int i = 1; i < nPoints; ++i)
            {
                if (poly[i].X < xMin) xMin = poly[i].X;
                if (poly[i].X > xMax) xMax = poly[i].X;
                if (poly[i].Y < yMin)
                {
                    yMin = poly[i].Y;
                    minY = i;
                }
                if (poly[i].Y > yMax) yMax = poly[i].Y;
            }

            float x1 = 0;
            float x2 = 0;
            float y1 = 0;
            float y2 = 0;
            float Xpos0 = 0;
            float[] Xpos = new float[16];
            float[] XXpos = new float[16];
            int[] ipos = new int[16];
            int irept = 0;

            int jj = 0;
            float yPos = yMin;
            float XXoffset = 0;

        L10: yPos += dist_linee;
            XXoffset += offset;
            if (yPos >= yMax) return;

            irept = 0;
            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y) ++irept;
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y) ++irept;
            }
            int irept2 = irept / 2;
            if (2 * irept2 < irept) goto L10;
            if (irept > 14) goto L10;
            ++jj;

            int inum = 0;
         {
                inum = 0;
                for (int ii = 0; ii < nPoints - 1; ++ii)
                {
                    if (poly[ii].Y > poly[ii + 1].Y)
                    {
                        if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y)
                        {
                            x1 = poly[ii].X;
                            x2 = poly[ii + 1].X;
                            y1 = poly[ii].Y;
                            y2 = poly[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (y1 - y2) + x2;
                            Xpos[inum] = Xpos0;
                            ++inum;
                        }
                        continue;
                    }
                    if (poly[ii].Y < poly[ii + 1].Y)
                        if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y)
                        {
                            x1 = poly[ii].X;
                            x2 = poly[ii + 1].X;
                            y1 = poly[ii].Y;
                            y2 = poly[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (y1 - y2) + x2;
                            Xpos[inum] = Xpos0;
                            ++inum;
                        }
                    if (inum >= 13) break;
                }

                for (int i = 0; i < inum; ++i) ipos[i] = 0;
                for (int j = 0; j < inum; ++j)
                {
                    int k = 0;
                    for (k = 0; k < inum; ++k)
                    {
                        if (ipos[k] == 0)
                        {
                            xMin = Xpos[k];
                            break;
                        }
                    }

                    int iptx = 0;
                    for (int i = 0; i < inum; ++i)
                    {
                        float fXP = Xpos[i];
                        if (i != k)
                        {
                            if (xMin > Xpos[i] && ipos[i] == 0)
                            {
                                xMin = Xpos[i];
                                iptx = i;
                            }
                        }
                        if (i == k) iptx = i;
                    }
                    XXpos[j] = Xpos[iptx];
                    ipos[iptx] = 1;
                }

                int imax = (inum + 1) / 2;
                float x5 = 0;
                float x6 = 0;
                float dashT = dash0 + dash1;
                PointF Pt1 = new PointF(x5, yPos);
                PointF Pt2 = new PointF(x6, yPos);
                for (int i = 0; i < imax; ++i)
                {
                    int j = 2 * i;

                    x5 = XXpos[j];
                    if (XXoffset < x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset + k * dashT >= x5)
                            {
                                float x55 = XXoffset + k * dashT;
                                x5 = x55;
                                break;
                            }
                    }
                    if (XXoffset > x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset - k * dashT <= x5)
                            {
                                float x55 = XXoffset - (k - 1) * dashT;
                                x5 = x55;
                                break;
                            }
                    }
                    xMax = XXpos[j + 1];
                    if (x5 > xMax) continue;

                    L30: x6 = x5 + dash0;
                    if (x6 > xMax) x6 = xMax;

                    Pt1.X = x5;
                    Pt2.X = x6;
                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax) goto L30;
                }
            }

            goto L10;

        }



        public struct areaInt
        {
            public int nPoints;
            public int ipnt;
            public float Xmin;
            public float Xmax;
            public float Ymin;
            public float Ymax;
        }


        public void arenile1(Graphics dc0, Pen iPen, int nVertices, float dash0, float dash1, float dist_linee, float offset, int ist, int lst)
        {
            //
            //          GUMAIN : 17/05/2014
            //
            char[] delimiterChars0 = { ',', '/' };
            string[] words;

            int nParts = ViewQ.vectShapesA[ist].nParts;

            int[] ipart = new int[nParts + 1];
            if (nParts > 1)
            {
                string sp = ViewQ.vectShapesA[ist].Parts_string;
                words = sp.Split(delimiterChars0);
                for (int j = 0; j < nParts; ++j) ipart[j] = int.Parse(words[j]);
            }
            else ipart[0] = 0;
            ipart[nParts] = nVertices;

            int[] lpart = new int[nParts + 1];
            areaInt[] vect = new areaInt[nParts + 1];

            int nPoints = 0;
            Point[] polygon = new Point[1];
            PointF[] poly1 = new PointF[1];
            PointF[] poly = new PointF[1];

            float xMin = 0;
            float xMax = 0;
            float yMin = 0;
            float yMax = 0;

            int Xorig = 0;
            int Yorig = 0;
            float scalaX = 0;
            float scalaY = 0;
            if (lst == 0)
            {
                Xorig = ViewQ.Xoff;
                Yorig = ViewQ.Yoff;
                scalaX = ViewQ.scalaX;
                scalaY = ViewQ.scalaY;
            }
            else
            {
                Xorig = Print.Xorig;
                Yorig = Print.Yorig;
                scalaX = Print.scalaX;
                scalaY = Print.scalaY;
            }
            //
            //      per ogni area interna definire i puntatori, i vettori con coordinate locali e rettangoli d'ingombro
            //
            //      fissare dei valori per lo schermo e la stampa
            float interp = 2;
            if (lst == 1) interp = 0.5F;
            //      nel loop seguente si considera il bordo esterno
            for (int k = 0; k < 1; ++k)
            {
                int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[k];
                int iVertices = ipart[k + 1] - ipart[k];
                polygon = new Point[iVertices];
                for (int j = 0; j < iVertices; ++j)
                {
                    polygon[j].X = (int)((ViewQ.PA[ipnt].X - ViewQ.Xmin) * scalaX) + Xorig;
                    polygon[j].Y = (int)((ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scalaY) + Yorig;
                    ++ipnt;
                }

                normalize(polygon, ref poly1, interp, ist);

                nPoints = poly1.Length;
                poly = new PointF[nPoints];

                ipnt = ipart[k];
                vect[k].ipnt = ipnt;
                vect[k].nPoints = nPoints;

                for (int i = 0; i < nPoints; ++i) poly[i + ipnt] = poly1[i];

                xMin = poly[ipnt].X;
                xMax = poly[ipnt].X;
                yMin = poly[ipnt].Y;
                yMax = poly[ipnt].Y;

                for (int i = 1; i < nPoints; ++i)
                {
                    int ii = i + ipnt;
                    if (poly[ii].X < xMin) xMin = poly[ii].X;
                    if (poly[ii].X > xMax) xMax = poly[ii].X;
                    if (poly[ii].Y < yMin) yMin = poly[ii].Y;
                    if (poly[ii].Y > yMax) yMax = poly[ii].Y;
                }
                vect[k].Xmin = xMin;
                vect[k].Xmax = xMax;
                vect[k].Ymin = yMin;
                vect[k].Ymax = yMax;
            }


            PointF[] poly11 = new PointF[1];
            PointF[] polyZ = new PointF[nVertices];

            int nPoints1 = 0;

            if (nParts == 1) goto L100;

            int mpnt = 0;

            //      nel loop seguente si considerano i bordi interni
            for (int k = 1; k < nParts; ++k)
            {
                int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[k];
                int iVertices = ipart[k + 1] - ipart[k];
                polygon = new Point[iVertices];
                for (int j = 0; j < iVertices; ++j)
                {
                    polygon[j].X = (int)((ViewQ.PA[ipnt].X - ViewQ.Xmin) * scalaX) + Xorig;
                    polygon[j].Y = (int)((ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scalaY) + Yorig;
                    ++ipnt;
                }

                normalize(polygon, ref poly1, interp, ist);

                nPoints = poly1.Length;

                vect[k].ipnt = mpnt;
                vect[k].nPoints = nPoints;

                for (int i = 0; i < nPoints; ++i) polyZ[i + mpnt] = poly1[i];

                xMin = polyZ[mpnt].X;
                xMax = polyZ[mpnt].X;
                yMin = polyZ[mpnt].Y;
                yMax = polyZ[mpnt].Y;

                for (int i = 1; i < nPoints; ++i)
                {
                    int ii = i + mpnt;
                    if (polyZ[ii].X < xMin) xMin = polyZ[ii].X;
                    if (polyZ[ii].X > xMax) xMax = polyZ[ii].X;
                    if (polyZ[ii].Y < yMin) yMin = polyZ[ii].Y;
                    if (polyZ[ii].Y > yMax) yMax = polyZ[ii].Y;
                }
                vect[k].Xmin = xMin;
                vect[k].Xmax = xMax;
                vect[k].Ymin = yMin;
                vect[k].Ymax = yMax;

                mpnt += nPoints;
            }
            vect[nParts].ipnt = mpnt;

        L100:
            float x1 = 0;
            float x2 = 0;
            float y2 = 0;
            float Xpos0 = 0;
            float[] Xpos = new float[20];
            float[] XXpos = new float[20];
            int[] ipos = new int[20];
            int irept = 0;
            int jj = 0;
            float yPos = vect[0].Ymin;
            float XXoffset = 0;

            int inumMax = 10 * nParts;
            float[] Xpos1 = new float[inumMax];
            float[] XXpos1 = new float[inumMax];
            int[] ipos1 = new int[inumMax];




        L10: yPos += dist_linee;
            XXoffset += offset;
            if (yPos >= vect[0].Ymax) return;
            //
            //      irept = numero di intersezioni della retta orizzontale yPos con il bordo esterno
            //
            irept = 0;
            nPoints = vect[0].nPoints;

            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y) ++irept;
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y) ++irept;
            }
            int irept2 = irept / 2;
            if (2 * irept2 < irept) goto L10;   //  le intersezioni dovrebbero essere di numero pari
            if (irept > 18) goto L10;
            ++jj;

            int inum = 0;

            // calcolo intersezioni retta orizzontale con bordo esterno 
            inum = 0;
            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                {
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y)
                    {
                        x1 = poly[ii].X;
                        x2 = poly[ii + 1].X;
                        y2 = poly[ii + 1].Y;
                        Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                        Xpos[inum] = Xpos0;
                        ++inum;
                    }
                    continue;
                }
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y)
                    {
                        x1 = poly[ii].X;
                        x2 = poly[ii + 1].X;
                        y2 = poly[ii + 1].Y;
                        Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                        Xpos[inum] = Xpos0;
                        ++inum;
                    }
                if (inum >= 18) break;
            }
            //
            //      riordino vettore Xpos secondo valori crescenti
            //
            for (int i = 0; i < inum; ++i) ipos[i] = 0;
            for (int j = 0; j < inum; ++j)
            {
                int k = 0;
                for (k = 0; k < inum; ++k)
                {
                    if (ipos[k] == 0)
                    {
                        xMin = Xpos[k];
                        break;
                    }
                }

                int iptx = 0;
                for (int i = 0; i < inum; ++i)
                {
                    float fXP = Xpos[i];
                    if (i != k)
                    {
                        if (xMin > Xpos[i] && ipos[i] == 0)
                        {
                            xMin = Xpos[i];
                            iptx = i;
                        }
                    }
                    if (i == k) iptx = i;
                }
                XXpos[j] = Xpos[iptx];
                ipos[iptx] = 1;
            }


            int imax = (inum + 1) / 2;
            float x5 = 0;
            float x6 = 0;
            float dashT = dash0 + dash1;
            PointF Pt1 = new PointF(x5, yPos);
            PointF Pt2 = new PointF(x6, yPos);

            for (int i = 0; i < imax; ++i)
            {
                int j = 2 * i;

                x5 = XXpos[j];
                if (XXoffset < x5)
                {
                    for (int k = 0; k < 1000; ++k) if (XXoffset + k * dashT >= x5)
                        {
                            x5 = XXoffset + k * dashT;
                            break;
                        }
                }
                if (XXoffset > x5)
                {
                    for (int k = 0; k < 1000; ++k) if (XXoffset - k * dashT <= x5)
                        {
                            x5 = XXoffset - (k - 1) * dashT;
                            break;
                        }
                }
                xMax = XXpos[j + 1];
                if (x5 > xMax) continue;

                //
                //          calcolo intersezioni con curva interna
                //
                if (nParts == 1) goto L30;

                inum = 0;
                for (int ik = 1; ik < nParts; ++ik)
                {
                    if (vect[ik].Ymin > yPos) continue;
                    if (vect[ik].Ymax < yPos) continue;
                    if (x5 > vect[ik].Xmax) continue;
                    if (xMax < vect[ik].Xmin) continue;
                    nPoints1 = vect[ik + 1].ipnt - vect[ik].ipnt;

                    mpnt = vect[ik].ipnt;
                    poly11 = new PointF[nPoints1];
                    for (int ii = 0; ii < nPoints1; ++ii) poly11[ii] = polyZ[ii + mpnt];

                    irept = 0;
                    for (int ii = 0; ii < nPoints1 - 1; ++ii)
                    {
                        if (poly11[ii].Y > poly11[ii + 1].Y)
                            if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y) ++irept;
                        if (poly11[ii].Y < poly11[ii + 1].Y)
                            if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y) ++irept;
                    }

                    if (irept == 0) continue;

                    float xx1 = 0;
                    float xx2 = 0;
                    float yy2 = 0;

                    for (int ii = 0; ii < nPoints1 - 1; ++ii)
                    {
                        if (poly11[ii].Y > poly11[ii + 1].Y)
                        {
                            if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y)
                            {
                                xx1 = poly11[ii].X;
                                xx2 = poly11[ii + 1].X;
                                yy2 = poly11[ii + 1].Y;
                                Xpos0 = (yPos - yy2) * (xx1 - xx2) / (poly11[ii].Y - yy2) + xx2;
                                Xpos1[inum] = Xpos0;
                                ++inum;
                            }
                            continue;
                        }
                        if (poly11[ii].Y < poly11[ii + 1].Y)
                            if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y)
                            {
                                xx1 = poly11[ii].X;
                                xx2 = poly11[ii + 1].X;
                                yy2 = poly11[ii + 1].Y;
                                Xpos0 = (yPos - yy2) * (xx1 - xx2) / (poly11[ii].Y - yy2) + xx2;
                                Xpos1[inum] = Xpos0;
                                ++inum;
                            }
                        if (inum >= inumMax) break;
                    }
                }

                //
                //      riordino vettore Xpos1 secondo valori crescenti
                //
                if (inum == 0) goto L30;
                for (int ik = 0; ik < inum; ++ik) ipos1[ik] = 0;
                for (int jk = 0; jk < inum; ++jk)
                {
                    int k = 0;
                    for (k = 0; k < inum; ++k)
                    {
                        if (ipos1[k] == 0)
                        {
                            xMin = Xpos1[k];
                            break;
                        }
                    }

                    int iptx = 0;
                    for (int ik = 0; ik < inum; ++ik)
                    {
                        float fXP = Xpos1[ik];
                        if (ik != k)
                        {
                            if (xMin > Xpos1[ik] && ipos1[ik] == 0)
                            {
                                xMin = Xpos1[ik];
                                iptx = ik;
                            }
                        }
                        if (ik == k) iptx = ik;
                    }
                    XXpos1[jk] = Xpos1[iptx];
                    ipos1[iptx] = 1;
                }

                int inum2 = inum / 2;
                int ip = 0;
                for (int ik = 0; ik < inum2; ++ik)
                {
                    float xMax1;
                    xMax1 = XXpos1[ip];
                L20: x6 = x5 + dash0;
                    if (x6 > xMax1) x6 = xMax1;

                    Pt1.X = x5;
                    Pt2.X = x6;
                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax1) goto L20;

                    x5 = XXpos1[ip + 1];

                    if (XXoffset < x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset + k * dashT >= x5)
                            {
                                x5 = XXoffset + k * dashT;
                                break;
                            }
                    }
                    else if (XXoffset > x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset - k * dashT <= x5)
                            {
                                x5 = XXoffset - k * dashT;
                                break;
                            }
                    }
                    ip += 2;
                }

            L25: x6 = x5 + dash0;
                if (x6 > xMax) x6 = xMax;

                Pt1.X = x5;
                Pt2.X = x6;
                dc0.DrawLine(iPen, Pt1, Pt2);
                x5 = x6 + dash1;
                if (x5 < xMax) goto L25;

                continue;

            L30: x6 = x5 + dash0;
                if (x6 > xMax) x6 = xMax;

                Pt1.X = x5;
                Pt2.X = x6;
                dc0.DrawLine(iPen, Pt1, Pt2);
                x5 = x6 + dash1;
                if (x5 < xMax) goto L30;
            }
            goto L10;

        }

        public void limiteDiBosco(Pen iPen, Point[] polygon, float width, float dash0, float dash1, float interp, float diam, Graphics dc0, int ist)
        {
            int nPoint = polygon.Length;
            if (nPoint < 3) return;
            PointF[] polyg = new PointF[nPoint];
            for (int i = 0; i < nPoint; ++i)
            {
                polyg[i].X = (float)polygon[i].X;
                polyg[i].Y = (float)polygon[i].Y;
            }
            limiteDiBosco(iPen, polyg, width, dash0, dash1, interp, diam, dc0, ist);
        }

        public void limiteDiBosco(Pen iPen, PointF[] polygon, float width, float dash0, float dash1, float interp, float diam, Graphics dc0, int ist)
        {
            int nPoint = polygon.Length;
            if (nPoint < 3) return;
            float ilen = polyLength(polygon, nPoint);
            if (ilen < 3 * interp) return;
            int maxPt = 2 * nPoint;
            int maxPt1 = 3 * (int)(ilen / interp);
            if (maxPt1 > maxPt) maxPt = maxPt1;
            PointF[] poly1 = new PointF[1];
            float interp1 = 0.1F * interp;
            normalize(polygon, ref poly1, interp1, ist);

            int nPoint1 = poly1.Length;
            if (nPoint1 < 3) return;
            //          float ilen3 = polyLength(poly1, nPoint1);

            PointF[] poly2 = new PointF[maxPt];

            int nPoints = newPoint(poly1, ref poly2, interp, maxPt, ist);

            for (int j = 0; j < nPoints; ++j)
            {
                float X = (poly2[j].X);
                float Y = (poly2[j].Y);
                dc0.DrawEllipse(iPen, X, Y, diam, diam);
            }

        }


        public void roccia(Graphics dc0, Pen iPen, int nVertices, float dash0, float dash1, float dist_linee, float inclinazione, int ist, int lst)
        {

            //
            //          GUMAIN : 17/05/2014
            //
            //            return;
            char[] delimiterChars0 = { ',', '/' };
            string[] words;

            int nParts = ViewQ.vectShapesA[ist].nParts;
            //   MessageBox.Show(ist.ToString() + "  " + nParts.ToString()+ "  " + nVertices.ToString());
            int[] ipart = new int[nParts + 1];
            if (nParts > 1)
            {
                string sp = ViewQ.vectShapesA[ist].Parts_string;
                words = sp.Split(delimiterChars0);
                for (int j = 0; j < nParts; ++j) ipart[j] = int.Parse(words[j]);
            }
            else ipart[0] = 0;
            ipart[nParts] = nVertices;

            double alphaR = 0;
            calcolo_inclinazione(ist, ref alphaR);
            double alpha = 180.0 * alphaR / Math.PI;
            alpha += inclinazione;
            alphaR = Math.PI * alpha / 180.0;

            int[] lpart = new int[nParts + 1];
            areaInt[] vect = new areaInt[nParts + 1];

            int nPoints = 0;
            Point[] polygon = new Point[1];
            PointF[] poly1 = new PointF[1];
            PointF[] poly = new PointF[1];

            float xMin = 0;
            float xMax = 0;
            float yMin = 0;
            float yMax = 0;

            int Xorig = 0;
            int Yorig = 0;
            float scalaX = 0;
            float scalaY = 0;
            if (lst == 0)
            {
                Xorig = ViewQ.Xoff;
                Yorig = ViewQ.Yoff;
                scalaX = ViewQ.scalaX;
                scalaY = ViewQ.scalaY;
            }
            else
            {
                Xorig = Print.Xorig;
                Yorig = Print.Yorig;
                scalaX = Print.scalaX;
                scalaY = Print.scalaY;
            }
            //
            //      per ogni area interna definire i puntatori, i vettori con coordinate locali e rettangoli d'ingombro
            //
            //      rotazione dell'area
            //
            float sinA = (float)Math.Sin(alphaR);
            float cosA = (float)Math.Cos(alphaR);

            //      fissare dei valori per lo schermo e la stampa
            float interp = 2;
            if (lst == 1) interp = 0.5F;
            //      nel loop seguente si considera il bordo esterno
            for (int k = 0; k < 1; ++k)
            {
                int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[k];
                int iVertices = ipart[k + 1] - ipart[k];
                polygon = new Point[iVertices];
                for (int j = 0; j < iVertices; ++j)
                {
                    float XX = (ViewQ.PA[ipnt].X - ViewQ.Xmin) * scalaX + Xorig;
                    float YY = (ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scalaY + Yorig;
                    polygon[j].X = (int)(XX * cosA + YY * sinA);
                    polygon[j].Y = (int)(-XX * sinA + YY * cosA);
                    ++ipnt;
                }

                normalize(polygon, ref poly1, interp, ist);

                nPoints = poly1.Length;
                poly = new PointF[nPoints];

                ipnt = ipart[k];
                vect[k].ipnt = ipnt;
                vect[k].nPoints = nPoints;

                for (int i = 0; i < nPoints; ++i) poly[i + ipnt] = poly1[i];

                xMin = poly[ipnt].X;
                xMax = poly[ipnt].X;
                yMin = poly[ipnt].Y;
                yMax = poly[ipnt].Y;

                for (int i = 1; i < nPoints; ++i)
                {
                    int ii = i + ipnt;
                    if (poly[ii].X < xMin) xMin = poly[ii].X;
                    if (poly[ii].X > xMax) xMax = poly[ii].X;
                    if (poly[ii].Y < yMin) yMin = poly[ii].Y;
                    if (poly[ii].Y > yMax) yMax = poly[ii].Y;
                }
                vect[k].Xmin = xMin;
                vect[k].Xmax = xMax;
                vect[k].Ymin = yMin;
                vect[k].Ymax = yMax;
            }


            PointF[] poly11 = new PointF[1];
            PointF[] polyZ = new PointF[nVertices];

            int nPoints1 = 0;

            if (nParts == 1) goto L100;

            int mpnt = 0;

            //      nel loop seguente si considerano i bordi interni
            for (int k = 1; k < nParts; ++k)
            {
                int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[k];
                int iVertices = ipart[k + 1] - ipart[k];
                polygon = new Point[iVertices];
                for (int j = 0; j < iVertices; ++j)
                {
                    float XX = (ViewQ.PA[ipnt].X - ViewQ.Xmin) * scalaX + Xorig;
                    float YY = (ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scalaY + Yorig;
                    polygon[j].X = (int)(XX * cosA + YY * sinA);
                    polygon[j].Y = (int)(-XX * sinA + YY * cosA);
                    ++ipnt;
                }

                normalize(polygon, ref poly1, interp, ist);

                nPoints = poly1.Length;

                vect[k].ipnt = mpnt;
                vect[k].nPoints = nPoints;

                for (int i = 0; i < nPoints; ++i) polyZ[i + mpnt] = poly1[i];

                xMin = polyZ[mpnt].X;
                xMax = polyZ[mpnt].X;
                yMin = polyZ[mpnt].Y;
                yMax = polyZ[mpnt].Y;

                for (int i = 1; i < nPoints; ++i)
                {
                    int ii = i + mpnt;
                    if (polyZ[ii].X < xMin) xMin = polyZ[ii].X;
                    if (polyZ[ii].X > xMax) xMax = polyZ[ii].X;
                    if (polyZ[ii].Y < yMin) yMin = polyZ[ii].Y;
                    if (polyZ[ii].Y > yMax) yMax = polyZ[ii].Y;
                }
                vect[k].Xmin = xMin;
                vect[k].Xmax = xMax;
                vect[k].Ymin = yMin;
                vect[k].Ymax = yMax;

                mpnt += nPoints;
            }
            vect[nParts].ipnt = mpnt;

        L100:
            float x1 = 0;
            float x2 = 0;
            float y2 = 0;
            float Xpos0 = 0;
            float[] Xpos = new float[20];
            float[] XXpos = new float[20];
            int[] ipos = new int[20];
            int irept = 0;
            int jj = 0;
            float yPos = vect[0].Ymin;

            int inumMax = 10 * nParts;
            float[] Xpos1 = new float[inumMax];
            float[] XXpos1 = new float[inumMax];
            int[] ipos1 = new int[inumMax];

        L10: yPos += dist_linee;

            if (yPos >= vect[0].Ymax) return;
            //
            //      irept = numero di intersezioni della retta orizzontale yPos con il bordo esterno
            //
            irept = 0;
            nPoints = vect[0].nPoints;

            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y) ++irept;
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y) ++irept;
            }
            int irept2 = irept / 2;
            if (2 * irept2 < irept) goto L10;   //  le intersezioni dovrebbero essere di numero pari
            if (irept > 18) goto L10;
            ++jj;

            int inum = 0;

            // calcolo intersezioni retta orizzontale con bordo esterno 
            inum = 0;
            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                {
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y)
                    {
                        x1 = poly[ii].X;
                        x2 = poly[ii + 1].X;
                        y2 = poly[ii + 1].Y;
                        Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                        Xpos[inum] = Xpos0;
                        ++inum;
                    }
                    continue;
                }
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y)
                    {
                        x1 = poly[ii].X;
                        x2 = poly[ii + 1].X;
                        y2 = poly[ii + 1].Y;
                        Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                        Xpos[inum] = Xpos0;
                        ++inum;
                    }
                if (inum >= 18) break;
            }
            //
            //      riordino vettore Xpos secondo valori crescenti
            //
            for (int i = 0; i < inum; ++i) ipos[i] = 0;
            for (int j = 0; j < inum; ++j)
            {
                int k = 0;
                for (k = 0; k < inum; ++k)
                {
                    if (ipos[k] == 0)
                    {
                        xMin = Xpos[k];
                        break;
                    }
                }

                int iptx = 0;
                for (int i = 0; i < inum; ++i)
                {
                    float fXP = Xpos[i];
                    if (i != k)
                    {
                        if (xMin > Xpos[i] && ipos[i] == 0)
                        {
                            xMin = Xpos[i];
                            iptx = i;
                        }
                    }
                    if (i == k) iptx = i;
                }
                XXpos[j] = Xpos[iptx];
                ipos[iptx] = 1;
            }


            int imax = (inum + 1) / 2;
            float x5 = 0;
            float x6 = 0;
            float dashT = dash0 + dash1;
            PointF Pt1 = new PointF(x5, yPos);
            PointF Pt2 = new PointF(x6, yPos);

            for (int i = 0; i < imax; ++i)
            {
                int j = 2 * i;

                x5 = XXpos[j];

                xMax = XXpos[j + 1];
                if (x5 > xMax) continue;

                //
                //          calcolo intersezioni con curva interna
                //
                if (nParts == 1) goto L30;

                inum = 0;
                for (int ik = 1; ik < nParts; ++ik)
                {
                    if (vect[ik].Ymin > yPos) continue;
                    if (vect[ik].Ymax < yPos) continue;
                    if (x5 > vect[ik].Xmax) continue;
                    if (xMax < vect[ik].Xmin) continue;
                    nPoints1 = vect[ik + 1].ipnt - vect[ik].ipnt;

                    mpnt = vect[ik].ipnt;
                    poly11 = new PointF[nPoints1];
                    for (int ii = 0; ii < nPoints1; ++ii) poly11[ii] = polyZ[ii + mpnt];

                    irept = 0;
                    for (int ii = 0; ii < nPoints1 - 1; ++ii)
                    {
                        if (poly11[ii].Y > poly11[ii + 1].Y)
                            if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y) ++irept;
                        if (poly11[ii].Y < poly11[ii + 1].Y)
                            if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y) ++irept;
                    }

                    if (irept == 0) continue;

                    float xx1 = 0;
                    float xx2 = 0;
                    float yy2 = 0;

                    for (int ii = 0; ii < nPoints1 - 1; ++ii)
                    {
                        if (poly11[ii].Y > poly11[ii + 1].Y)
                        {
                            if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y)
                            {
                                xx1 = poly11[ii].X;
                                xx2 = poly11[ii + 1].X;
                                yy2 = poly11[ii + 1].Y;
                                Xpos0 = (yPos - yy2) * (xx1 - xx2) / (poly11[ii].Y - yy2) + xx2;
                                Xpos1[inum] = Xpos0;
                                ++inum;
                            }
                            continue;
                        }
                        if (poly11[ii].Y < poly11[ii + 1].Y)
                            if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y)
                            {
                                xx1 = poly11[ii].X;
                                xx2 = poly11[ii + 1].X;
                                yy2 = poly11[ii + 1].Y;
                                Xpos0 = (yPos - yy2) * (xx1 - xx2) / (poly11[ii].Y - yy2) + xx2;
                                Xpos1[inum] = Xpos0;
                                ++inum;
                            }
                        if (inum >= inumMax) break;
                    }
                }

                //
                //      riordino vettore Xpos1 secondo valori crescenti
                //
                if (inum == 0) goto L30;
                for (int ik = 0; ik < inum; ++ik) ipos1[ik] = 0;
                for (int jk = 0; jk < inum; ++jk)
                {
                    int k = 0;
                    for (k = 0; k < inum; ++k)
                    {
                        if (ipos1[k] == 0)
                        {
                            xMin = Xpos1[k];
                            break;
                        }
                    }

                    int iptx = 0;
                    for (int ik = 0; ik < inum; ++ik)
                    {
                        float fXP = Xpos1[ik];
                        if (ik != k)
                        {
                            if (xMin > Xpos1[ik] && ipos1[ik] == 0)
                            {
                                xMin = Xpos1[ik];
                                iptx = ik;
                            }
                        }
                        if (ik == k) iptx = ik;
                    }
                    XXpos1[jk] = Xpos1[iptx];
                    ipos1[iptx] = 1;
                }


                int inum2 = inum / 2;
                int ip = 0;
                for (int ik = 0; ik < inum2; ++ik)
                {
                    float xMax1;
                    xMax1 = XXpos1[ip];
                L20: x6 = x5 + dash0;
                    if (x6 > xMax1) x6 = xMax1;

                    Pt1.X = x5 * cosA - yPos * sinA;
                    Pt1.Y = x5 * sinA + yPos * cosA;
                    Pt2.X = x6 * cosA - yPos * sinA; ;
                    Pt2.Y = x6 * sinA + yPos * cosA;
                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax1) goto L20;

                    x5 = XXpos1[ip + 1];
                    ip += 2;
                }

            L25: x6 = x5 + dash0;
                if (x6 > xMax) x6 = xMax;

                //               Pt1.X = x5;
                //              Pt2.X = x6;
                Pt1.X = x5 * cosA - yPos * sinA;
                Pt1.Y = x5 * sinA + yPos * cosA;
                Pt2.X = x6 * cosA - yPos * sinA; ;
                Pt2.Y = x6 * sinA + yPos * cosA;
                dc0.DrawLine(iPen, Pt1, Pt2);
                x5 = x6 + dash1;
                if (x5 < xMax) goto L25;

                continue;

            L30: x6 = x5 + dash0;
                if (x6 > xMax) x6 = xMax;

                Pt1.X = x5 * cosA - yPos * sinA;
                Pt1.Y = x5 * sinA + yPos * cosA;
                Pt2.X = x6 * cosA - yPos * sinA; ;
                Pt2.Y = x6 * sinA + yPos * cosA;
                dc0.DrawLine(iPen, Pt1, Pt2);
                x5 = x6 + dash1;
                if (x5 < xMax) goto L30;
            }
            goto L10;

        }

        private void calcolo_inclinazione(int ist, ref double alphaR)
        {
            //
            //
            //
            char[] delimiterChars0 = { ',', '/' };
            string[] words;
            NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;

            int nParts = ViewQ.vectShapesA[ist].nParts;
            int nVertices = ViewQ.vectShapesA[ist].nVertices;

            int[] ipart = new int[nParts + 1];
            if (nParts > 1)
            {
                string sp = ViewQ.vectShapesA[ist].Parts_string;
                words = sp.Split(delimiterChars0);
                for (int j = 0; j < nParts; ++j) ipart[j] = int.Parse(words[j]);
            }
            else ipart[0] = 0;
            ipart[nParts] = nVertices;
            //
            //        selezione punti o vertici del contorno esterno dell'area
            //

            int ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[0];
            int nPoints = ipart[1] - ipart[0];
            if (nPoints < 10) return;

            int inc = 1;
            int iPoints = 0;

        L5: iPoints = nPoints - 100 * inc;
            if (iPoints > 0)
            {
                ++inc;
                goto L5;
            }
            nPoints = nPoints / inc;

            Point[] polygon = new Point[nPoints];

            for (int i = 0; i < nPoints; ++i)
            {
                polygon[i].X = ViewQ.PA[ipnt].X;
                polygon[i].Y = ViewQ.PA[ipnt].Y;
                ipnt += inc;
            }

            int[] elev = new int[nPoints];
            Point Hit = new Point(0, 0);
            int isel_max = 300;
            int[] ipt = new int[isel_max];
            int[] elev1 = new int[isel_max];
            //
            //          calcolo quota dei vertici del contorno esterno dell'area
            //                    
            for (int i = 0; i < nPoints; ++i)
            {
                Hit.X = polygon[i].X;
                Hit.Y = polygon[i].Y;
                //
                //          prima selezione curve di livello vicine al vertice i
                //          la ricerca viene effettuata con il criterio delle aree incluse nei rettangoli di definizione
                //          delle curve di livello
                //
                int isel = 0;
                for (int j = 0; j < ViewQ.nShapes; ++j)
                {
                    int pntSimb = ViewQ.vectShapes[j].pntSimb;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000CD")) goto L11;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000CI")) goto L11;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000DI")) goto L11;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000II")) goto L11;
                    continue;
                L11:
                    if (Hit.X < ViewQ.vectShapes[j].PointA.X) continue;
                    if (Hit.X > ViewQ.vectShapes[j].PointB.X) continue;
                    if (ViewQ.vectShapes[j].PointA.Y < ViewQ.vectShapes[j].PointB.Y)
                    {
                        if (Hit.Y < ViewQ.vectShapes[j].PointA.Y) continue;
                        if (Hit.Y > ViewQ.vectShapes[j].PointB.Y) continue;
                    }
                    else
                    {
                        if (Hit.Y > ViewQ.vectShapes[j].PointA.Y) continue;
                        if (Hit.Y < ViewQ.vectShapes[j].PointB.Y) continue;

                    }
                    ipt[isel] = j;
                    ++isel;
                    if (isel == isel_max)
                    {
                        MessageBox.Show("superato limite vettore ipt :" + isel_max.ToString() + " per area " + ist.ToString());
                        break;
                    }
                }

                if (isel == isel_max) return;

                //
                //          seconda selezione curve di livello vicine al vertice i
                //
                int idiff = 30;

                int X1 = Hit.X - idiff;
                int Y1 = Hit.Y - idiff;
                int X2 = Hit.X + idiff;
                int Y2 = Hit.Y + idiff;

                int nsel = 0;

                for (int j = 0; j < isel; ++j)
                {
                    int jj = ipt[j];
                    int iVertices = ViewQ.vectShapes[jj].nVertices;
                    int lpnt = ViewQ.vectShapes[jj].pntpL;

                    int kk = 0;
                    for (kk = 0; kk < iVertices; ++kk)
                    {
                        int i1 = 0;
                        if (ViewQ.PL[lpnt].X > X1 && (ViewQ.PL[lpnt].X < X2)) ++i1;
                        if (ViewQ.PL[lpnt].Y > Y1 && (ViewQ.PL[lpnt].Y < Y2)) ++i1;
                        if (i1 == 2) break;
                        ++lpnt;
                    }
                    if (kk < iVertices) ++nsel;
                    else ipt[j] = -jj;
                }

                if (nsel == 0)
                {
                    //              MessageBox.Show("non trovata nessuna linea che comprenda il punto selezionato - 3 " + ist.ToString() +  " " + isel.ToString());
                    //      è possibile che le curve di ivello abiano origine nelle aree di roccia ad es. area 14 elemento 33131
                    return;
                }
                //
                //              ricerca della curva più vicina al vertice i
                //
                int[] hMin = new int[isel];
                for (int j = 0; j < isel; ++j)
                {
                    int jj = ipt[j];
                    elev1[j] = 0;
                    hMin[j] = -1;
                    if (jj < 0) continue;
                    elev1[j] = (int)float.Parse(ViewQ.vectShapes[jj].quota, nfi);
                    if (elev1[j] == 0) continue;
                    int iVertices = ViewQ.vectShapes[jj].nVertices;
                    int lpnt = ViewQ.vectShapes[jj].pntpL;
                    int[] vect1 = new int[iVertices];
                    //
                    //              calcolo distanza di ogni curva dal vertice i
                    //
                    for (int m = 0; m < iVertices; ++m)
                    {
                        int xdiff = ViewQ.PL[lpnt].X - Hit.X;
                        int ydiff = ViewQ.PL[lpnt].Y - Hit.Y;
                        vect1[m] = xdiff * xdiff + ydiff * ydiff;
                        ++lpnt;
                    }

                    int ixMin = vect1[0];
                    int mm = 0;
                    for (int m = 1; m < iVertices; ++m)
                    {
                        if (ixMin > vect1[m])
                        {
                            ixMin = vect1[m];
                            mm = m;
                        }
                    }
                    hMin[j] = ixMin;
                }
                int j1 = 0;
                for (j1 = 0; j1 < isel; ++j1) if (ipt[j1] > 0) break;
                if (j1 == isel)
                {
                    MessageBox.Show("area " + ist.ToString() + " anomala " + i.ToString() + " " + nsel.ToString() + " " + nPoints.ToString() + " " + nVertices.ToString());
                    return;
                }
                int xMin1 = hMin[j1];
                int jj1 = j1;
                for (int j = j1; j < isel; ++j)
                {
                    if (ipt[j] < 0) continue;
                    if (xMin1 > hMin[j])
                    {
                        xMin1 = hMin[j];
                        jj1 = j;
                    }
                }

                elev[i] = elev1[jj1];
            }
            //
            //          quota minima e massima del contorno
            //
            int hMin1 = elev[0];
            int mm1 = 0;
            int hMax = elev[0];
            int mm2 = 0;
            for (int i = 0; i < nPoints; ++i)
            {
                if (hMin1 > elev[i])
                {
                    hMin1 = elev[i];
                    mm1 = i;
                }
                if (hMax < elev[i])
                {
                    hMax = elev[i];
                    mm2 = i;
                }
            }
            int lskip = 1;
            if(lskip == 1) goto L20;                        //  da rivedere
            float limSup = hMin1 + 0.2F * (hMax - hMin1);
            int inum = 0;
            for (int i = 0; i < nPoints; ++i) if (elev[i] <= limSup) ++inum;
            Point[] poly2 = new Point[inum];

            int ip = 0;
            for (int i = 0; i < nPoints; ++i)
            {
                if (elev[i] > limSup) continue;
                poly2[ip] = polygon[i];
                ++ip;
            }

            //
            //          linea di regressione passante per i punti più bassi
            //
            float AA = 0;
            regress(poly2, ref AA, ist);
            alphaR = Math.Atan((double)AA);

            return;

        L20:
            int ix1 = polygon[mm1].X;
            int iy1 = polygon[mm1].Y;
            int ix2 = polygon[mm2].X;
            int iy2 = polygon[mm2].Y;
            int idx = ix2 - ix1;
            int idy = iy2 - iy1;
            int dxx = idx;
            if (idx < 0) dxx = -idx;
            if (dxx < 5)
            {
                alphaR = Math.PI / 2;
            }
            else
            {
                alphaR = Math.Atan2((double)idy, (double)idx);
            }

        }

        private void regress(Point[] poly2, ref float AA, int ist)
        {

            int inum = poly2.Length;

            float x1 = 0;
            float y1 = 0;
            for (int i = 0; i < inum; ++i)
            {
                x1 += poly2[i].X;
                y1 += poly2[i].Y;
            }

            float x2 = 0;
            for (int i = 0; i < inum; ++i)
            {
                x2 += poly2[i].X * poly2[i].X;
            }

            float x1y1 = 0;
            for (int i = 0; i < inum; ++i)
            {
                x1y1 += poly2[i].X * poly2[i].Y;
            }

            AA = (inum * x1y1 - x1 * y1) / (inum * x2 - x1 * x1);
        }


        public void roccia22(Graphics dc0, Pen iPen, int nVertices, float dash0, float dash1, float dist_linee, float inclinazione, int ist, int lst)
        {

            char[] delimiterChars0 = { ',', '/' };
            string[] words;
            NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;

            int nParts = ViewQ.vectShapesA[ist].nParts;

            int[] ipart = new int[nParts + 1];
            if (nParts > 1)
            {
                string sp = ViewQ.vectShapesA[ist].Parts_string;
                words = sp.Split(delimiterChars0);
                for (int j = 0; j < nParts; ++j) ipart[j] = int.Parse(words[j]);
            }
            else ipart[0] = 0;
            ipart[nParts] = nVertices;
            //
            //        selezione punti o vertici del contorno esterno dell'area
            //
            int nPoints = 0;
            Point[] polygon = new Point[1];
            int[] elev = new int[1];
            int ipnt = 0;
            for (int i = 0; i < 1; ++i)
            {
                ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[i];
                nPoints = ipart[i + 1] - ipart[i];
                polygon = new Point[nPoints];
                elev = new int[nPoints];
                for (int j = 0; j < nPoints; ++j)
                {
                    polygon[j].X = ViewQ.PA[ipnt].X;
                    polygon[j].Y = ViewQ.PA[ipnt].Y;
                    ++ipnt;
                }
            }
            int mskip = 1;
  /****/    if(mskip == 1) goto L50;             //  da rivedere
            Point Hit = new Point(0, 0);
            int isel_max = 300;
            int[] ipt = new int[isel_max];
            int[] elev1 = new int[isel_max];
            //
            //          calcolo quota dei vertici del contorno esterno dell'area
            //                    
            for (int i = 0; i < nPoints; ++i)
            {
                Hit.X = polygon[i].X;
                Hit.Y = polygon[i].Y;
                //
                //          prima selezione curve di livello vicine al vertice i
                //          la ricerca viene effettuata con il criterio delle aree incluse neirettangoli di definizione
                //          delle curev di livello
                //
                int isel = 0;
                for (int j = 0; j < ViewQ.nShapes; ++j)
                {
                    int pntSimb = ViewQ.vectShapes[j].pntSimb;
                    int iskip = 0;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000CD")) iskip = 1; 
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000CI")) iskip = 1;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000DI")) iskip = 1;
                    if (ViewQ.vectS[pntSimb].codice.Contains("1L000II")) iskip = 1;

                    if (iskip == 1)
                    {
                        if (Hit.X < ViewQ.vectShapes[j].PointA.X) continue;
                        if (Hit.X > ViewQ.vectShapes[j].PointB.X) continue;
                        if (ViewQ.vectShapes[j].PointA.Y < ViewQ.vectShapes[j].PointB.Y)
                        {
                            if (Hit.Y < ViewQ.vectShapes[j].PointA.Y) continue;
                            if (Hit.Y > ViewQ.vectShapes[j].PointB.Y) continue;
                        }
                        else
                        {
                            if (Hit.Y > ViewQ.vectShapes[j].PointA.Y) continue;
                            if (Hit.Y < ViewQ.vectShapes[j].PointB.Y) continue;

                        }
                        ipt[isel] = j;
                        ++isel;
                        if (isel == isel_max)
                        {
                            MessageBox.Show("superato limite vettore ipt :" + isel_max.ToString());
                            break;
                        }
                    }
                }
                //
                //          seconda selezione curve di livello vicine al vertice i
                //
                int idiff = 30;

                int X1 = Hit.X - idiff;
                int Y1 = Hit.Y - idiff;
                int X2 = Hit.X + idiff;
                int Y2 = Hit.Y + idiff;

                int nsel = 0;

                for (int j = 0; j < isel; ++j)
                {
                    int jj = ipt[j];
                    int iVertices = ViewQ.vectShapes[jj].nVertices;
                    int lpnt = ViewQ.vectShapes[jj].pntpL;

                    int kk = 0;
                    for (kk = 0; kk < iVertices; ++kk)
                    {
                        int i1 = 0;
                        if (ViewQ.PL[lpnt].X > X1 && (ViewQ.PL[lpnt].X < X2)) ++i1;
                        if (ViewQ.PL[lpnt].Y > Y1 && (ViewQ.PL[lpnt].Y < Y2)) ++i1;
                        if (i1 == 2) break;
                        ++lpnt;
                    }
                    if (kk < iVertices) ++nsel;
                    else ipt[j] = -jj;
                }

                if (nsel == 0)
                {
                    //              MessageBox.Show("non trovata nessuna linea che comprenda il punto selezionato - 3 " + ist.ToString() +  " " + isel.ToString());
                    //      è possibile che le curve di ivello abiano origine nelle aree di roccia ad es. area 14 elemento 33131
                    return;
                }
                //
                //              ricerca della curva più vicina al vertice i
                //
                int[] hMin = new int[isel];
                for (int j = 0; j < isel; ++j)
                {
                    int jj = ipt[j];
                    elev1[j] = 0;
                    hMin[j] = -1;
                    if (jj < 0) continue;
                    elev1[j] = (int)float.Parse(ViewQ.vectShapes[jj].quota, nfi);
                    if (elev1[j] == 0) continue;
                    int iVertices = ViewQ.vectShapes[jj].nVertices;
                    int lpnt = ViewQ.vectShapes[jj].pntpL;
                    int[] vect1 = new int[iVertices];
                    //
                    //              calcolo distanza di ogni curva dal vertice i
                    //
                    for (int m = 0; m < iVertices; ++m)
                    {
                        int xdiff = ViewQ.PL[lpnt].X - Hit.X;
                        int ydiff = ViewQ.PL[lpnt].Y - Hit.Y;
                        vect1[m] = xdiff * xdiff + ydiff * ydiff;
                        ++lpnt;
                    }

                    int ixMin = vect1[0];
                    int mm = 0;
                    for (int m = 1; m < iVertices; ++m)
                    {
                        if (ixMin > vect1[m])
                        {
                            ixMin = vect1[m];
                            mm = m;
                        }
                    }
                    hMin[j] = ixMin;
                }
                int j1 = 0;
                for (j1 = 0; j1 < isel; ++j1) if (ipt[j1] > 0) break;
                if (j1 == isel)
                {
                    MessageBox.Show("area " + ist.ToString() + " anomala " + i.ToString() + " " + nsel.ToString() + " " + nPoints.ToString() + " " + nVertices.ToString());
                    return;
                }
                int xMin1 = hMin[j1];
                int jj1 = j1;
                for (int j = j1; j < isel; ++j)
                {
                    if (ipt[j] < 0) continue;
                    if (xMin1 > hMin[j])
                    {
                        xMin1 = hMin[j];
                        jj1 = j;
                    }
                }

                elev[i] = elev1[jj1];
            }
            //
            //          quota minima e massima del contorno
            //
            int hMin1 = elev[0];
            int mm1 = 0;
            int hMax = elev[0];
            int mm2 = 0;
            for (int i = 0; i < nPoints; ++i)
            {
                if (hMin1 > elev[i])
                {
                    hMin1 = elev[i];
                    mm1 = i;
                }
                if (hMax < elev[i])
                {
                    hMax = elev[i];
                    mm2 = i;
                }
            }
            float limSup = hMin1 + 0.2F * (hMax - hMin1);
            int inum = 0;
            for (int i = 0; i < nPoints; ++i) if (elev[i] <= limSup) ++inum;
            Point[] poly2 = new Point[inum];

            int ip = 0;
            for (int i = 0; i < nPoints; ++i)
            {
                if (elev[i] > limSup) continue;
                poly2[ip] = polygon[i];
                ++ip;
            }

            //
            //          linea di regressione passante per i punti più bassi
            //
            float AA = 0;
            regress(poly2, ref AA, ist);
            double alphaR = Math.Atan((double)AA);

        L50:       /********/
        AA = 0;
            alphaR = Math.Atan((double)AA);
            double alpha = 180.0 * alphaR / Math.PI;
            alpha -= inclinazione;
            alphaR = Math.PI * alpha / 180.0;

            //
            //          riduzione a coordinate locali
            //
            PointF[] poly1 = new PointF[1];
            PointF[] poly = new PointF[1];
            areaInt[] vect = new areaInt[nParts];

            int kVertices = ipart[1] - ipart[0];
            polygon = new Point[kVertices];
            ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[0];
            int Xorig = 0;
            int Yorig = 0;
            float scalaX = 0;
            float scalaY = 0;
            if (lst == 0)
            {
                Xorig = ViewQ.Xoff;
                Yorig = ViewQ.Yoff;
                scalaX = ViewQ.scalaX;
                scalaY = ViewQ.scalaY;
            }
            else
            {
                Xorig = Print.Xorig;
                Yorig = Print.Yorig;
                scalaX = Print.scalaX;
                scalaY = Print.scalaY;
            }
            for (int j = 0; j < kVertices; ++j)
            {
                polygon[j].X = (int)((ViewQ.PA[ipnt].X - ViewQ.Xmin) * scalaX) + Xorig;
                polygon[j].Y = (int)((ViewQ.PA[ipnt].Y - ViewQ.Ymin) * scalaY) + Yorig;
                ++ipnt;
            }
            float interp = 1;
            normalize(polygon, ref poly1, interp, ist);

            nPoints = poly1.Length;
            //
            //          rotazione dell'area
            //
            float sinA = (float)Math.Sin(alphaR);
            float cosA = (float)Math.Cos(alphaR);

            poly = new PointF[nPoints];
            for (int i = 0; i < nPoints; ++i)
            {
                poly[i].X = poly1[i].X * cosA + poly1[i].Y * sinA;
                poly[i].Y = -poly1[i].X * sinA + poly1[i].Y * cosA;
            }

            ipnt = 0;
            float xMin = poly[ipnt].X;
            float xMax = poly[ipnt].X;
            float yMin = poly[ipnt].Y;
            float yMax = poly[ipnt].Y;

            for (int i = 1; i < nPoints; ++i)
            {
                if (poly[i].X < xMin) xMin = poly[i].X;
                if (poly[i].X > xMax) xMax = poly[i].X;
                if (poly[i].Y < yMin) yMin = poly[i].Y;
                if (poly[i].Y > yMax) yMax = poly[i].Y;
            }
            vect[0].ipnt = 0;
            vect[0].nPoints = nPoints;
            vect[0].Xmin = xMin;
            vect[0].Xmax = xMax;
            vect[0].Ymin = yMin;
            vect[0].Ymax = yMax;
            //
            //          parti interne del contorno
            //
            int nPoints1 = 0;
            PointF[] poly11 = new PointF[1];
            if (nParts > 1)
            {
                Point[] polygon1 = new Point[1];

                for (int k = 1; k < 2; ++k)
                {
                    ipnt = ViewQ.vectShapesA[ist].pntPA + ipart[k];
                    int iVertices = ipart[k + 1] - ipart[k];
                    polygon1 = new Point[iVertices];
                    for (int j = 0; j < iVertices; ++j)
                    {
                        polygon1[j].X = (int)((ViewQ.PA[ipnt].X - ViewQ.Xmin) * ViewQ.scalaX) + ViewQ.Xoff;
                        polygon1[j].Y = (int)((ViewQ.PA[ipnt].Y - ViewQ.Ymin) * ViewQ.scalaY) + ViewQ.Yoff;
                        ++ipnt;
                    }
                }

                float interp1 = 2;
                normalize(polygon1, ref poly11, interp1, ist);

                nPoints1 = poly11.Length;
            }
            //
            //          loop
            //

            float x1 = 0;
            float x2 = 0;
            float y2 = 0;
            float Xpos0 = 0;
            float[] Xpos = new float[20];
            float[] XXpos = new float[20];
            int[] ipos = new int[20];
            int irept = 0;

            int jk = 0;
            float yPos = vect[0].Ymin;
            float XXoffset = 0;

        L10: yPos += dist_linee;
            //        XXoffset += offset;
            if (yPos >= vect[0].Ymax) return;

            irept = 0;
            nPoints = vect[0].nPoints;
            //  calcolo numero intersezioni retta orizzontale con contorno esterno
            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y) ++irept;
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y) ++irept;
            }
            int irept2 = irept / 2;
            if (2 * irept2 < irept) goto L10;
            if (irept > 18) goto L10;
            ++jk;
            //  calcolo posizione intersezioni  
            inum = 0;
            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                {
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y)
                    {
                        x1 = poly[ii].X;
                        x2 = poly[ii + 1].X;
                        y2 = poly[ii + 1].Y;
                        Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                        Xpos[inum] = Xpos0;
                        ++inum;
                    }
                    continue;
                }
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y)
                    {
                        x1 = poly[ii].X;
                        x2 = poly[ii + 1].X;
                        y2 = poly[ii + 1].Y;
                        Xpos0 = (yPos - y2) * (x1 - x2) / (poly[ii].Y - y2) + x2;
                        Xpos[inum] = Xpos0;
                        ++inum;
                    }
                if (inum >= 13) break;
            }
            //  ordinamento posizioni
            for (int ik = 0; ik < inum; ++ik) ipos[ik] = 0;
            for (int j = 0; j < inum; ++j)
            {
                int k = 0;
                for (k = 0; k < inum; ++k)
                {
                    if (ipos[k] == 0)
                    {
                        xMin = Xpos[k];
                        break;
                    }
                }

                int iptx = 0;
                for (int ik = 0; ik < inum; ++ik)
                {
                    float fXP = Xpos[ik];
                    if (ik != k)
                    {
                        if (xMin > Xpos[ik] && ipos[ik] == 0)
                        {
                            xMin = Xpos[ik];
                            iptx = ik;
                        }
                    }
                    if (ik == k) iptx = ik;
                }
                XXpos[j] = Xpos[iptx];
                ipos[iptx] = 1;
            }



            int imax = (inum + 1) / 2;
            float x5 = 0;
            float x6 = 0;
            float dashT = dash0 + dash1;
            PointF Pt1 = new PointF(x5, yPos);
            PointF Pt2 = new PointF(x6, yPos);

            for (int i = 0; i < imax; ++i)
            {
                int j = 2 * i;

                x5 = XXpos[j];

                xMax = XXpos[j + 1];
                if (x5 > xMax) continue;


                irept = 0;
                for (int ii = 0; ii < nPoints1 - 1; ++ii)           //  se nParts > 1
                {
                    if (poly11[ii].Y > poly11[ii + 1].Y)
                        if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y) ++irept;
                    if (poly11[ii].Y < poly11[ii + 1].Y)
                        if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y) ++irept;
                }

                if (irept == 0) goto L30;

                inum = 0;
                float[] Xpos1 = new float[20];
                float[] XXpos1 = new float[20];
                int[] ipos1 = new int[20];

                for (int ii = 0; ii < nPoints1 - 1; ++ii)
                {
                    if (poly11[ii].Y > poly11[ii + 1].Y)
                    {
                        if (yPos >= poly11[ii + 1].Y && yPos < poly11[ii].Y)
                        {
                            x1 = poly11[ii].X;
                            x2 = poly11[ii + 1].X;
                            y2 = poly11[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (poly11[ii].Y - y2) + x2;
                            Xpos1[inum] = Xpos0;
                            ++inum;
                        }
                        continue;
                    }
                    if (poly11[ii].Y < poly11[ii + 1].Y)
                        if (yPos < poly11[ii + 1].Y && yPos >= poly11[ii].Y)
                        {
                            x1 = poly11[ii].X;
                            x2 = poly11[ii + 1].X;
                            y2 = poly11[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (poly11[ii].Y - y2) + x2;
                            Xpos1[inum] = Xpos0;
                            ++inum;
                        }
                    if (inum >= 17) break;
                }

                for (int ik = 0; ik < inum; ++ik) ipos1[ik] = 0;
                for (j = 0; j < inum; ++j)
                {
                    int k = 0;
                    for (k = 0; k < inum; ++k)
                    {
                        if (ipos1[k] == 0)
                        {
                            xMin = Xpos1[k];
                            break;
                        }
                    }

                    int iptx = 0;
                    for (int ik = 0; ik < inum; ++ik)
                    {
                        float fXP = Xpos1[ik];
                        if (ik != k)
                        {
                            if (xMin > Xpos1[ik] && ipos1[ik] == 0)
                            {
                                xMin = Xpos1[ik];
                                iptx = ik;
                            }
                        }
                        if (ik == k) iptx = ik;
                    }
                    XXpos1[j] = Xpos1[iptx];
                    ipos1[iptx] = 1;
                }

                if (inum == 2)
                {
                    float xMax1;
                    xMax1 = XXpos1[0];
                L20: x6 = x5 + dash0;
                    if (x6 > xMax1) x6 = xMax1;

                    Pt1.X = x5 * cosA - yPos * sinA;
                    Pt1.Y = x5 * sinA + yPos * cosA;
                    Pt2.X = x6 * cosA - yPos * sinA; ;
                    Pt2.Y = x6 * sinA + yPos * cosA;

                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax1) goto L20;

                    x5 = XXpos1[1];
                    //
                    if (XXoffset < x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset + k * dashT >= x5)
                            {
                                x5 = XXoffset + k * dashT;
                                break;
                            }
                    }
                    if (XXoffset > x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset - k * dashT <= x5)
                            {
                                x5 = XXoffset - k * dashT;
                                break;
                            }
                    }
                //
                L25: x6 = x5 + dash0;
                    if (x6 > xMax) x6 = xMax;


                    Pt1.X = x5 * cosA - yPos * sinA;
                    Pt1.Y = x5 * sinA + yPos * cosA;
                    Pt2.X = x6 * cosA - yPos * sinA; ;
                    Pt2.Y = x6 * sinA + yPos * cosA;

                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax) goto L25;
                }

                if (inum == 4)
                {
                    float xMax1;
                    xMax1 = XXpos1[0];
                L26: x6 = x5 + dash0;
                    if (x6 > xMax1) x6 = xMax1;

                    Pt1.X = x5 * cosA - yPos * sinA;
                    Pt1.Y = x5 * sinA + yPos * cosA;
                    Pt2.X = x6 * cosA - yPos * sinA; ;
                    Pt2.Y = x6 * sinA + yPos * cosA;

                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax1) goto L26;

                    x5 = XXpos1[1];
                    if (XXoffset < x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset + k * dashT >= x5)
                            {
                                x5 = XXoffset + k * dashT;
                                break;
                            }
                    }
                    if (XXoffset > x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset - k * dashT <= x5)
                            {
                                x5 = XXoffset - k * dashT;
                                break;
                            }
                    }
                    xMax1 = XXpos1[2];
                L27: x6 = x5 + dash0;
                    if (x6 > xMax) x6 = xMax1;

                    Pt1.X = x5 * cosA - yPos * sinA;
                    Pt1.Y = x5 * sinA + yPos * cosA;
                    Pt2.X = x6 * cosA - yPos * sinA; ;
                    Pt2.Y = x6 * sinA + yPos * cosA;

                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax1) goto L27;

                    x5 = XXpos1[3];
                    if (XXoffset < x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset + k * dashT >= x5)
                            {
                                x5 = XXoffset + k * dashT;
                                break;
                            }
                    }
                    if (XXoffset > x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset - k * dashT <= x5)
                            {
                                x5 = XXoffset - k * dashT;
                                break;
                            }
                    }
                    xMax1 = XXpos1[2];
                L28: x6 = x5 + dash0;
                    if (x6 > xMax) x6 = xMax;

                    Pt1.X = x5 * cosA - yPos * sinA;
                    Pt1.Y = x5 * sinA + yPos * cosA;
                    Pt2.X = x6 * cosA - yPos * sinA; ;
                    Pt2.Y = x6 * sinA + yPos * cosA;

                    dc0.DrawLine(iPen, Pt1, Pt2);
                    x5 = x6 + dash1;
                    if (x5 < xMax) goto L28;
                }

                continue;

            L30: x6 = x5 + dash0;
                if (x6 > xMax) x6 = xMax;

                Pt1.X = x5 * cosA - yPos * sinA;
                Pt1.Y = x5 * sinA + yPos * cosA;
                Pt2.X = x6 * cosA - yPos * sinA; ;
                Pt2.Y = x6 * sinA + yPos * cosA;

                dc0.DrawLine(iPen, Pt1, Pt2);
                x5 = x6 + dash1;
                if (x5 < xMax) goto L30;
            }
            goto L10;



        }
        public void limiteDiBosco(PdfFileWriter.PdfContents Contents, PointF[] polygon, double width, double dash0, double dash1, double interp, double diam, int ist)
        {
            int nPoint = polygon.Length;
            if (nPoint < 3) return;
            float ilen = polyLength(polygon, nPoint);
            if (ilen < 3 * interp) return;
            int maxPt = 2 * nPoint;
            int maxPt1 = 3 * (int)(ilen / interp);
            if (maxPt1 > maxPt) maxPt = maxPt1;
            PointF[] poly1 = new PointF[1];
            float interp1 = 0.1F * (float)interp;
            normalize(polygon, ref poly1, interp1, ist);

            int nPoint1 = poly1.Length;
            if (nPoint1 < 3) return;
            //          float ilen3 = polyLength(poly1, nPoint1);

            PointF[] poly2 = new PointF[maxPt];

            int nPoints = newPoint(poly1, ref poly2, (float)interp, maxPt, ist);

            for (int j = 0; j < nPoints; ++j)
            {
                double X = (poly2[j].X);
                double Y = (poly2[j].Y);
                Contents.DrawOval(X, Y, diam, diam, PaintOp.CloseStroke);
            }

        }

        public void scarpata(PdfFileWriter.PdfContents Contents, PointF[] polygon, double width, double dash0, double dash1, double interp, int ist, int type)
        {
            int nPoint = polygon.Length;
            if (nPoint < 3) return;
            float ilen = polyLength(polygon, nPoint);
            if (ilen < 3 * interp) return;
            int maxPt = 2 * nPoint;  // 3 * (int)(ilen / interp);
            int maxPt1 = 3 * (int)(ilen / interp);
            if (maxPt1 > maxPt) maxPt = maxPt1;

            PointF[] poly1 = new PointF[1];
            float interp1 = 0.2F * (float)interp;
            normalize(polygon, ref poly1, interp1, ist);

            int nPoint1 = poly1.Length;
            if (nPoint1 < 3) return;

            PointF[] poly2 = new PointF[maxPt];
            int nPoints = newPoint(poly1, ref poly2, (float)interp, maxPt, ist);

            poly1 = new PointF[nPoints];

            float dash00 = (float)dash0;
            float dash11 = (float)dash1;
            if (ViewQ.scalaXY < 2)
            {
                dash00 = (float)dash0 / 2;
                dash11 = (float)dash1 / 2;
            }
            if (type == 11 || type == 13) puntoAdiacente(poly2, ref poly1, nPoints, dash00, dash11, ist);
            if (type == 12) puntoAdiacente1(ref poly2, ref poly1, nPoints, dash00, dash11, ist);
            for (int j = 0; j < nPoints; ++j)
            {
                //              dc0.DrawLine(iPen, poly2[j], poly1[j]);
                double X1 = poly2[j].X;
                double Y1 = poly2[j].Y;
                double X2 = poly1[j].X;
                double Y2 = poly1[j].Y;

                Contents.DrawLine(X1, Y1, X2, Y2);
            }
            if (type == 13)
            {
                drawLines(Contents, poly2);
            }
        }

        void drawLines(PdfContents Contents, PointF[] polyD)
        {
            int len = polyD.Length;
            int ipt = 0;
            Contents.SetPaintOp(PaintOp.Stroke);
            for (int i = 0; i < len - 1; ++i)
            {
                double X1 = polyD[ipt].X;
                double Y1 = polyD[ipt].Y;
                ++ipt;
                double X2 = polyD[ipt].X;
                double Y2 = polyD[ipt].Y;

                Contents.DrawLine(X1, Y1, X2, Y2);
            }
        }

        public void arenile(PdfFileWriter.PdfContents Contents, PointF[] polygon, double dash0, double dash1, double dist_linee, double offset, int ist)
        {

            PointF[] poly1 = new PointF[1];
            float interp = 2;
            normalize(polygon, ref poly1, interp, ist);

            int nPoints = poly1.Length;
            PointF[] poly = new PointF[nPoints + 1];

            for (int i = 0; i < nPoints; ++i) poly[i] = poly1[i];

            float yMin = poly[0].Y;
            float yMax = poly[0].Y;
            float xMin = poly[0].X;
            float xMax = poly[0].X;
            int minY = 0;
            for (int i = 1; i < nPoints; ++i)
            {
                if (poly[i].X < xMin) xMin = poly[i].X;
                if (poly[i].X > xMax) xMax = poly[i].X;
                if (poly[i].Y < yMin)
                {
                    yMin = poly[i].Y;
                    minY = i;
                }
                if (poly[i].Y > yMax) yMax = poly[i].Y;
            }

            float x1 = 0;
            float x2 = 0;
            float y1 = 0;
            float y2 = 0;
            float Xpos0 = 0;
            float[] Xpos = new float[16];
            float[] XXpos = new float[16];
            int[] ipos = new int[16];
            int irept = 0;

            int jj = 0;
            float yPos = yMin;
            float XXoffset = 0;

        L10: yPos += (float)dist_linee;
            XXoffset += (float)offset;
            if (yPos >= yMax) return;

            irept = 0;
            for (int ii = 0; ii < nPoints - 1; ++ii)
            {
                if (poly[ii].Y > poly[ii + 1].Y)
                    if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y) ++irept;
                if (poly[ii].Y < poly[ii + 1].Y)
                    if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y) ++irept;
            }
            int irept2 = irept / 2;
            if (2 * irept2 < irept) goto L10;
            if (irept > 14) goto L10;
            ++jj;

            int inum = 0;
          {
                inum = 0;
                for (int ii = 0; ii < nPoints - 1; ++ii)
                {
                    if (poly[ii].Y > poly[ii + 1].Y)
                    {
                        if (yPos >= poly[ii + 1].Y && yPos < poly[ii].Y)
                        {
                            x1 = poly[ii].X;
                            x2 = poly[ii + 1].X;
                            y1 = poly[ii].Y;
                            y2 = poly[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (y1 - y2) + x2;
                            Xpos[inum] = Xpos0;
                            ++inum;
                        }
                        continue;
                    }
                    if (poly[ii].Y < poly[ii + 1].Y)
                        if (yPos < poly[ii + 1].Y && yPos >= poly[ii].Y)
                        {
                            x1 = poly[ii].X;
                            x2 = poly[ii + 1].X;
                            y1 = poly[ii].Y;
                            y2 = poly[ii + 1].Y;
                            Xpos0 = (yPos - y2) * (x1 - x2) / (y1 - y2) + x2;
                            Xpos[inum] = Xpos0;
                            ++inum;
                        }
                    if (inum >= 13) break;
                }

                for (int i = 0; i < inum; ++i) ipos[i] = 0;
                for (int j = 0; j < inum; ++j)
                {
                    int k = 0;
                    for (k = 0; k < inum; ++k)
                    {
                        if (ipos[k] == 0)
                        {
                            xMin = Xpos[k];
                            break;
                        }
                    }

                    int iptx = 0;
                    for (int i = 0; i < inum; ++i)
                    {
                        float fXP = Xpos[i];
                        if (i != k)
                        {
                            if (xMin > Xpos[i] && ipos[i] == 0)
                            {
                                xMin = Xpos[i];
                                iptx = i;
                            }
                        }
                        if (i == k) iptx = i;
                    }
                    XXpos[j] = Xpos[iptx];
                    ipos[iptx] = 1;
                }

                int imax = (inum + 1) / 2;
                float x5 = 0;
                float x6 = 0;
                float dashT = (float)(dash0 + dash1);
                PointF Pt1 = new PointF(x5, yPos);
                PointF Pt2 = new PointF(x6, yPos);
                for (int i = 0; i < imax; ++i)
                {
                    int j = 2 * i;

                    x5 = XXpos[j];
                    if (XXoffset < x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset + k * dashT >= x5)
                            {
                                float x55 = XXoffset + k * dashT;
                                x5 = x55;
                                break;
                            }
                    }
                    if (XXoffset > x5)
                    {
                        for (int k = 0; k < 1000; ++k) if (XXoffset - k * dashT <= x5)
                            {
                                float x55 = XXoffset - (k - 1) * dashT;
                                x5 = x55;
                                break;
                            }
                    }
                    xMax = XXpos[j + 1];
                    if (x5 > xMax) continue;

                    L30: x6 = x5 + (float)dash0;
                    if (x6 > xMax) x6 = xMax;

                    Pt1.X = x5;
                    Pt2.X = x6;
                    double X1 = Pt1.X;
                    double Y1 = Pt1.Y;
                    double X2 = Pt2.X;
                    double Y2 = Pt2.Y;

                    Contents.DrawLine(X1, Y1, X2, Y2);
                    x5 = x6 + (float)dash1;
                    if (x5 < xMax) goto L30;
                }
            }

            goto L10;

        }

        public void dashLine(PdfFileWriter.PdfContents Contents, PointF[] polyD, double width, double[] dashValues, int type, int ist)
        {
            bool bTratt = false;
            if (type == 33 || type == 43 || type == 44 || type == 60) bTratt = true;
            if (!bTratt) return;

            int nPoint = polyD.Length;
            float ilen = polyLength(polyD, nPoint);

            float interp = (float)dashValues[0];
            if (ilen < 3 * interp) return;
            int maxPt = 5 * nPoint;  // 3 * (int)(ilen / interp);
            int maxPt1 = 8 * (int)(ilen / interp);
            if (maxPt1 > maxPt) maxPt = maxPt1;

            PointF[] poly1 = new PointF[1];
            float interp1 = 0.35F;      // = 25.04/72
            normalize(polyD, ref poly1, interp1, ist);

            PointF[] poly2 = new PointF[maxPt];
            int nPoints = newPoint1(poly1, ref poly2, dashValues, ist);

            int ipt = 0;
            for (int j = 0; j < nPoints / 2; ++j)
            {
                double X1 = poly2[ipt].X;
                double Y1 = poly2[ipt].Y;
                double X2 = poly2[ipt + 1].X;
                double Y2 = poly2[ipt + 1].Y;
                Contents.DrawLine(X1, Y1, X2, Y2);

                ipt = ipt + 2;
            }
        }


        int newPoint1(PointF[] poly1, ref PointF[] poly2, double[] dash, int ist)
        {

            int ilen = poly1.Length;
            int maxIpt = poly2.Length;
            int idash = dash.Length;
            poly2[0] = poly1[0];
            int ipt = 1;
            //         MessageBox.Show("  ilen  " + ilen.ToString());

            bool bDraw = true;
            double dint = dash[0];
            double seg1 = 0;
            double XX = 0;
            double YY = 0;

            for (int i = 1; i < ilen; ++i)
            {
                double dx = poly1[i].X - poly1[i - 1].X;
                double dy = poly1[i].Y - poly1[i - 1].Y;
                double len = Math.Sqrt(dx * dx + dy * dy);
                double cos1 = dx / len;
                double sin1 = dy / len;

                double incrX = 0;
                double incrY = 0;
                bool bInit = false;

                if (seg1 != 0)
                {
                    XX = seg1 * cos1;
                    YY = seg1 * sin1;
                    bInit = true;
                }

            L10: if (bDraw) dint = dash[0];
                else dint = dash[1];

                double diff = len - seg1;
                if (!bInit) diff -= dint;

                if (diff >= 0)
                {
                    if (bInit)
                    {
                        incrX = XX;
                        incrY = YY;
                    }
                    else
                    {
                        incrX += dint * cos1;
                        incrY += dint * sin1;
                    }
                    poly2[ipt].X = poly1[i - 1].X + (float)incrX;
                    poly2[ipt].Y = poly1[i - 1].Y + (float)incrY;
                    ++ipt;
                    if (bDraw)
                    {
                        bDraw = false;
                    }
                    else
                    {
                        bDraw = true;
                    }
                    if (ipt >= maxIpt) break;

                    if (!bInit) seg1 += dint;
                    bInit = false;
                    goto L10;
                }

                if (diff < 0)
                {
                    if (bDraw)
                    {
                        poly2[ipt].X = poly1[i].X;
                        poly2[ipt].Y = poly1[i].Y;
                        ++ipt;
                        if (i < ilen - 1)
                        {
                            poly2[ipt].X = poly1[i].X;
                            poly2[ipt].Y = poly1[i].Y;
                            ++ipt;
                        }
                    }

                    if (ipt >= maxIpt) break;
                    seg1 = -diff;
                }
            }
            return (ipt);
        }


    }
}

